package org.qh.common.access.processor;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;

import org.apache.commons.lang3.ObjectUtils;
import org.qh.common.access.definition.AccessHandler;
import org.qh.common.access.definition.AccessPrincipal;
import org.qh.common.access.definition.AccessResponse;
import org.qh.common.access.definition.AccessUserDetails;
import org.qh.common.access.enums.AccountType;
import org.qh.common.core.constant.SymbolConstants;
import org.qh.common.core.exception.BusinessException;

/**
 * <p>Description: 微信小程序接入处理器 </p>
 */
public class MiniProgramAccessHandler implements AccessHandler {

    private final MiniProgramProcessor miniProgramProcessor;

    public MiniProgramAccessHandler(MiniProgramProcessor miniProgramProcessor) {
        this.miniProgramProcessor = miniProgramProcessor;
    }

    @Override
    public AccessResponse preProcess(String core, String... params) {
        WxMaJscode2SessionResult wxMaSession = miniProgramProcessor.login(core, params[0]);
        if (ObjectUtils.isNotEmpty(wxMaSession)) {
            AccessResponse accessResponse = new AccessResponse();
            accessResponse.setSession(wxMaSession);
            return accessResponse;
        }

        throw new BusinessException("mini program login failed");
    }

    @Override
    public AccessUserDetails loadUserDetails(String source, AccessPrincipal accessPrincipal, AccessResponse accessResponse) {

        WxMaJscode2SessionResult session = accessResponse.getSession();
        String sessionKey = session.getSessionKey();
        String openId = session.getOpenid();
        String unionId = session.getUnionid();

        WxMaUserInfo wxMaUserInfo = miniProgramProcessor.getUserInfo(accessPrincipal.getAppId(), sessionKey, accessPrincipal.getEncryptedData(), accessPrincipal.getIv());
        AccessUserDetails accessUserDetails = new AccessUserDetails();
        if (ObjectUtils.isEmpty(wxMaUserInfo)) {
            throw new BusinessException("Can not find the userinfo from Wechat!");
        }

        this.convertWxMaUserInfoToAccessUserDetails(accessUserDetails, wxMaUserInfo, accessPrincipal);

        WxMaPhoneNumberInfo phoneNumberInfo = miniProgramProcessor.getPhoneNumberInfo(accessPrincipal.getAppId(), accessPrincipal.getAccessCode());
        if (ObjectUtils.isNotEmpty(phoneNumberInfo)) {
            accessUserDetails.setPhoneNumber(phoneNumberInfo.getPhoneNumber());
        }

        if (ObjectUtils.isNotEmpty(accessResponse)) {
            accessUserDetails.setOpenId(openId);
            accessUserDetails.setUnionId(unionId);
        }
        return accessUserDetails;
    }

    private void convertWxMaUserInfoToAccessUserDetails(AccessUserDetails accessUserDetails, WxMaUserInfo wxMaUserInfo, AccessPrincipal accessPrincipal) {
        accessUserDetails.setUuid(accessPrincipal.getOpenId());
        accessUserDetails.setUserName(wxMaUserInfo.getNickName());
        accessUserDetails.setNickName(wxMaUserInfo.getNickName());
        accessUserDetails.setAvatar(wxMaUserInfo.getAvatarUrl());
        accessUserDetails.setLocation(wxMaUserInfo.getCountry() + SymbolConstants.FORWARD_SLASH + wxMaUserInfo.getProvince() + SymbolConstants.FORWARD_SLASH + wxMaUserInfo.getCity());
        accessUserDetails.setSource(AccountType.MINI_PROGRAM.name());
        accessUserDetails.setOpenId(accessPrincipal.getOpenId());
        accessUserDetails.setUnionId(accessPrincipal.getUnionId());
        accessUserDetails.setAppId(wxMaUserInfo.getWatermark().getAppid());
        accessUserDetails.setPhoneNumber(wxMaUserInfo.getWatermark().getAppid());
    }
}
